package com.learn.concurrent.leetcode.p1116;

import java.util.concurrent.Semaphore;

/**
 * 用CountDownLatch实现
 */
public class ZeroEvenOdd2 {

    private int n;

    private Semaphore zeroSema = new Semaphore(1);
    private Semaphore oddSema = new Semaphore(0);//奇数
    private Semaphore evenSema = new Semaphore(0);//偶数

    public ZeroEvenOdd2(int n) {
        this.n = n;
    }

    /**
     * 打印奇数
     */
    private void printZero() {
        for(int i=1;i<n;i++){
            try {
                zeroSema.acquire();
                System.out.println(Thread.currentThread()+"打印0");
                if((i&1)==1){
                    oddSema.release();
                }else{
                    evenSema.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    /**
     * 打印偶数
     */
    private void printEven() {
        for(int i=1;i<n;i++){
            try {
                if((i&1)==0){
                    evenSema.acquire();
                    System.out.println(Thread.currentThread()+" 打印偶数 "+i);
                    zeroSema.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 打印奇数
     */
    private void printOdd() {
        for(int i=1;i<n;i++){
            try {
                if((i&1)==1){
                    oddSema.acquire();;
                    System.out.println(Thread.currentThread()+ "打印奇数 "+i);
                    zeroSema.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //线程A 打印0
    //线程B 打印偶数
    //线程C 打印奇数
    //符合条件的线程运行，不符合条件的线程阻塞

    public static void main(String[] args) {
        ZeroEvenOdd2 zeroEvenOdd = new ZeroEvenOdd2(20);

        new Thread(new Runnable() {
            @Override
            public void run() {
                zeroEvenOdd.printZero();
            }
        },"零线程").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                zeroEvenOdd.printEven();
            }
        }, "偶数线程").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                zeroEvenOdd.printOdd();
            }
        }, "奇数线程").start();
    }

}